﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ReadeAssetManager
{
    public partial class frmService : Form
    {
        private AMSServiceRef.ServiceData _serv;
        private AMSServiceRef.Asset _asset;
        private AMSServiceRef.User _user;
        private const string INVALID_INPUT = "The title, company, date, and price fields cannot be empty.  Please re-enter.";
        private const string VERIFY_DELETE = "You are about to delete this service record.\n\n" +
                                             "Are you sure you want to delete this record?";
        private const string ERROR_LOAD_SERV = "An error occurred while loading this service record.";
        
        /// <summary>
        /// Constructor.
        /// This overload is used to create a new Service record.
        /// </summary>
        /// <param name="CurrentAsset">[AMSServiceRef.Asset] The asset record that will contain the new
        /// Service record.</param>
        public frmService(AMSServiceRef.Asset CurrentAsset)
        {
            InitializeComponent();
            _asset = CurrentAsset;
            _user = _asset.Owner;
            _serv = new AMSServiceRef.ServiceData();
            _serv.BaseItem = _asset;
            this.Text = _asset.Name + " New Service";
        }

        // constructor to edit a service record
        /// <summary>
        /// Constructor.
        /// This overload is used to modify an existing Service record.
        /// </summary>
        /// <param name="CurrentService">[AMSServiceRef.ServiceData] The existing Service record to view
        /// or modify.</param>
        public frmService(AMSServiceRef.ServiceData CurrentService)
        {
            InitializeComponent();
            _serv = CurrentService;
            _user = _serv.BaseItem.Owner;
            PopulateFormOptions();
            PopulateFormValues();
        }

        /// <summary>
        /// AddServiceToAsset
        /// Determines whether this Service record already exists in the Asset.  If not, adds the Service
        /// record to the Asset services list.  Otherwise, simply returns.
        /// </summary>
        private void AddServiceToAsset()
        {
            if (_serv.BaseItem.Purchases != null)
            {
                foreach (AMSServiceRef.ServiceData s in _serv.BaseItem.Services)
                {
                    if (s.Equals(_serv))
                        return;
                }
            }
            else
                _serv.BaseItem.Services = new List<AMSServiceRef.ServiceData>();

            _serv.BaseItem.Services.Add(_serv);
        }

        /// <summary>
        /// PopulateFormValues
        /// Fills the userform fields from the global AMSServiceRef.ServiceData object.  Displays an
        /// error if the service data could not be accessed (such as the Service is not instantiated).
        /// </summary>
        private void PopulateFormValues()
        {
            try
            {
                txtTitle.Text = _serv.Title;
                txtComp.Text = _serv.Company;
                txtPrice.Text = _serv.Price.ToString();
                txtComments.Text = _serv.Comments;
                dtpDate.Value = _serv.Date;
                cbIsWarr.Checked = _serv.UnderWarranty;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ERROR_LOAD_SERV + "\n\n" + ex.Message, "Error Loading Service Record");
            }
        }

        /// <summary>
        /// PopulateFormOptions
        /// Loads the form title and dropdown menu bar domains.
        /// </summary>
        private void PopulateFormOptions()
        {
            ToolStripMenuItem[] items;

            this.Text = _serv.BaseItem.Name + " Service: " + _serv.Title + " " + _serv.Date.ToShortDateString();

            // Load all available images
            if (_serv.Images != null)
            {
                items = new ToolStripMenuItem[_serv.Images.Count];
                for (int i = 0; i < _serv.Images.Count; i++)
                {
                    AMSServiceRef.AMSImage a = _serv.Images[i];
                    items[i] = CreateMenuItem(a, "mnuAssetImages" + a.ID, a.Caption, new EventHandler(LoadImageItem));
                }
                mnuServiceRecordsImages.DropDownItems.AddRange(items);
            }
            else
                _serv.Images = new List<AMSServiceRef.AMSImage>();
        }

        /// <summary>
        /// CreateMenuItem
        /// Creates a ToolStripMenuItem to represent the domain record for this Service.
        /// </summary>
        /// <param name="TagItem">[object] The domain object to be added to the MenuItem tag.</param>
        /// <param name="Name">[string] The MenuItem name.</param>
        /// <param name="Text">[string] The MenuItem text.</param>
        /// <param name="ClickEvent">[EventHandler] The event that should be raised when the user clicks the MenuItem.</param>
        /// <returns>[ToolStripMenuItem] The menu item representing this domain object.</returns>
        private ToolStripMenuItem CreateMenuItem(object TagItem, string Name,
                                                string Text, EventHandler ClickEvent)
        {
            ToolStripMenuItem tsmi = new ToolStripMenuItem();
            tsmi.Name = Name;
            tsmi.Text = Text;
            tsmi.Tag = TagItem;
            tsmi.Click += ClickEvent;

            return tsmi;
        }

        /// <summary>
        /// LoadImageItem
        /// EventHandler for an Image MenuItem.  This functionality is not implemented.
        /// </summary>
        /// <param name="sender">[object] The MenuItem that raised this event.</param>
        /// <param name="e">[EventArgs] The standard event arguments for a Click event.</param>
        private void LoadImageItem(object sender, EventArgs e)
        {
            // Open the images form with ((ToolStripMenuItem)sender).Tag
            MessageBox.Show("Images are not yet implemented.", "Not Implemented");
        }

        /// <summary>
        /// PopulateScheduleFromFields
        /// Loads all values from the userform into the current AMSServiceRef.ServiceData object.
        /// </summary>
        private void PopulateServiceFromFields()
        {
            double tmpprice;

            _serv.Title = txtTitle.Text;
            if (Double.TryParse(txtPrice.Text, out tmpprice))
                _serv.Price = tmpprice;
            _serv.Company = txtComp.Text;
            _serv.Comments = txtComments.Text;
            _serv.Date = dtpDate.Value;
            _serv.UnderWarranty = cbIsWarr.Checked;
        }

        /// <summary>
        /// SaveService
        /// Validates the user input, hydrates the object from the userform controls, and attempts
        /// to save the service record.  If the save is successful, attempts to add a new ServiceData 
        /// to the asset's services list and refreshes the frmMain asset list.
        /// </summary>
        /// <returns>[bool] True if the schedule record was successfully saved, otherwise false.</returns>
        private bool SaveService()
        {
            if (IsValidInput())
            {
                PopulateServiceFromFields();
                AMSServiceRef.AMSServiceClient c = new AMSServiceRef.AMSServiceClient();
                AMSServiceRef.ServiceData tmps = c.SaveService(_serv);
                if (tmps != null)
                {
                    _serv = tmps;
                    _user = _serv.BaseItem.Owner;
                    AddServiceToAsset();
                    ((frmMain)MdiParent).RefreshAssetList(_user);
                    return true;
                }
                return false;
            }
            else
            {
                MessageBox.Show(INVALID_INPUT);
                return false;
            }
        }

        /// <summary>
        /// IsValidInput
        /// Validates the user input based on database requirements.
        /// </summary>
        /// <returns>[bool] True if the input is valid, otherwise false.</returns>
        private bool IsValidInput()
        {
            return (txtTitle.Text.Length > 0) &&
                   (txtComp.Text.Length > 0) &&
                   (txtPrice.Text.Length > 0) &&
                   (dtpDate.Value != default(DateTime));
        }

        private void mnuServiceServiceSave_Click(object sender, EventArgs e)
        {
            if (!SaveService())
                MessageBox.Show("Unable to save service record.");
        }

        private void mnuServiceServiceSaveClose_Click(object sender, EventArgs e)
        {
            if (!SaveService())
            {
                if (MessageBox.Show("Unable to save changes.  Do you still want to close?", "Save Failed", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No)
                    return;
            }
            this.Close();
        }

        private void mnuServiceRecordsImagesNew_Click(object sender, EventArgs e)
        {
            // Create a new image record for this service.
        }

        private void mnuServiceServiceDelete_Click(object sender, EventArgs e)
        {
            if (_serv.ID > 0)
            {
                if (MessageBox.Show(VERIFY_DELETE, "Delete Service Record", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                {
                    AMSServiceRef.AMSServiceClient c = new AMSServiceRef.AMSServiceClient();
                    if (c.DeleteService(_serv))
                    {
                        _serv.BaseItem.Services.Remove(_serv);
                        ((frmMain)MdiParent).RefreshAssetList(_user);
                        this.Close();
                    }
                    else
                        MessageBox.Show("Unable to delete service record. " + _serv.Company + " dated " +
                                            _serv.Date.ToShortDateString() + ".");
                }
            }
        }
    }
}
